/*
 * Copyright (c) 2017. Visionet and/or its affiliates. All right reserved.
 * VISIONET PROPRIETARY/CONFIDENTIAL.
 */
package com.visionet.jumper.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

/**
 * json <-> java bean 转换工具类
 * @author TC.Ubuntu
 * @since 2017/7/3.
 */
public class JsonUtils {

	private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);

	private static ObjectMapper mapper = new ObjectMapper();

	static {
		mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		mapper.disable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS);
		mapper.disable(SerializationFeature.WRITE_NULL_MAP_VALUES);
		mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
		mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		mapper.setTimeZone(TimeZone.getDefault());
		mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
		mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
	}

	/**
	 * java 对象转换成 json 字符串
	 */
	public static String toJsonString(Object object) {
		try {
			return mapper.writeValueAsString(object);
		} catch (IOException e) {
			logger.error("write to json string error:" + object, e);
			return null;
		}
	}

	/**
	 * json 字符串转换成Java对象
	 */
	public static <T> T toObject(String jsonString, Class<T> clazz) {
		if (StringUtils.isEmpty(jsonString)) {
			return null;
		}
		try {
			return mapper.readValue(jsonString, clazz);
		} catch (IOException e) {
			logger.error("parse json string error:" + jsonString, e);
			return null;
		}
	}

	/**
	 * json 字符串转换成复杂Java 集合对象(List(bean) ..etc)
	 * @param jsonString json 字符串
	 * @param collectionClass java集合类型
	 * @param elementClasses 集合元素类型
	 */
	public static <T> T toObject(String jsonString, Class<?> collectionClass, Class<?>... elementClasses) {
		JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
		if (StringUtils.isEmpty(jsonString)) {
			return null;
		}
		try {
			return (T) mapper.readValue(jsonString, javaType);
		} catch (IOException e) {
			logger.error("parse json string error:" + jsonString, e);
			return null;
		}
	}

	/**
	 * inputStream --> java object
	 */
	public static <T> T toObject(InputStream inputStream, Class<T> clazz) {
		if (inputStream == null) {
			return null;
		}
		try {
			return mapper.readValue(inputStream, clazz);
		} catch (IOException e) {
			logger.error("parse json string error:" + inputStream, e);
			return null;
		}
	}

	/**
	 * inputStream 转换成复杂Java 集合对象(List(bean) ..etc)
	 * @param inputStream 输入流
	 * @param collectionClass java集合类型
	 * @param elementClasses 集合元素类型
	 */
	public static <T> T toObject(InputStream inputStream, Class<?> collectionClass, Class<?>... elementClasses) {
		JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
		if (inputStream == null) {
			return null;
		}
		try {
			return (T) mapper.readValue(inputStream, javaType);
		} catch (IOException e) {
			logger.error("parse json string error:" + inputStream, e);
			return null;
		}
	}

	public static void toOutputStream(OutputStream outputStream, Object object) {
		try {
			mapper.writeValue(outputStream, object);
		} catch (Exception e) {
			logger.error("parse json string error:" + outputStream, e);
		}
	}
}
